=======================================================
"TENLINER OTHELLO" - A ZX-SPECTRUM GAME BY EINAR SAUKAS
=======================================================

-----
INTRO
-----

This is a ZX-Spectrum program that plays the classic board game OTHELLO (also
known as REVERSI), coded in 10 lines only.

You can play against a strong computer AI or another player. The computer AI is
also able to choose best moves for human players whenever they ask for help.


----------
GAME RULES
----------

In each turn, the player must place a new disk on the board. Whenever one or
more enemy disks are "trapped" in a straigh line between your new disk and one
of your old disks, all these enemy disks are captured. You are only allowed to
place a disk when it captures at least one enemy disk. And you are only allowed
to pass when it's not possible to capture anything. The gameplay is fully
explained here:

https://en.wikipedia.org/wiki/Reversi


------------
INSTRUCTIONS
------------

When you run this game, it will first ask how many players. Type 1 (and press
ENTER) for single player mode against the computer AI, or type 2 (and press
ENTER) for 2 players mode.

Afterwards, you will see the initial board. You always start playing as blue,
and the computer (or another human opponent) plays as red. The screen border
shows the current player's turn.

When it's your turn, you will see a flashing cursor at the botton of screen. To
play at a certain position on the board, type a row number (and press ENTER),
then type a column number (and press ENTER). If your move is valid, your new
disk will appear on the board as a lighter color (cyan for blue player, magenta
for red player), and the entire board will be updated depending on captured
disks. Otherwise if you tried an invalid move, the game will simply ask you to
try again. Remember that valid moves must always capture enemy disks.

During the game, it can happen that there may not be any valid moves available.
In that case, simply type 0 for both row and column. Typing 0 also means asking
the computer AI for help. In this case, the computer AI will either choose the
best possible valid move for you, or pass your turn if there are no valid moves.

The game will finish when the board is full, or one player lost all disks, or
there are no more valid moves for both players. When it happens, the player with
highest number of disks wins.


-------
LISTING
-------

Type the following program in a ZX-Spectrum in "48K BASIC" mode:

1x:dt(91):i"Players (1-2)?";f:RESTORE:READ n,t(41),t(42),t(50),t(51),t(1),z,p,z$
2lp=3-p:lq=z>1:dc(3):fa=1 TO 8:fb=1 TO 8:lk=t(a*9+b+1):pAT 18,3*b+2;b
3pAT a+a,2;a;PAPER k+p*p*(a*9+b+1=z);AT a+a,3*b+1;"/  ";AT a+a+1,3*b+1;"___"
4lc(k+1)=c(k+1)+1:nb:na:p''" BLUE ";c(2);"x";c(3);" RED",:bp
5le=c(1)*c(p+1)>0:i':ue*f>=p THEN i"Row (0-8)? ";a'"Col (0-8)? ";b
6fi=1 TO 62*e:lz=CODE z$(i)-32+(a*9+b)*(a*b>0)*(b<9)
7BEEP .01,i:fj=0 TO 9*(t(z)=0)-1:ld=j+INT (j/3)*6-10:lw=z+d
8on-2,8:ut(w)=3-p THEN lw=w+d:o(t(w)<>p)*n,1:lw=w-d:lt(w)=p:o(w<>z)*n,4
9nj:g2+(8*(i*q<62)-5*(z>1=i))*(t(z)*j=0):DATA 23620,2,1,1,2,3,2,2
10ni:b7:DATA "!2j+qX=0-ol_D?ZB]HT\@[QAKOF/.nmVMYPG>^ULC9876fedcka4,ph;1:bg5!"

Every letter typed at the beginning of a new line, or immediately after a colon
":" or statement "THEN", will be instantly replaced with its corresponding 
command by the ZX-Spectrum interpreter, as follows:

    a = NEW                                 n = NEXT
    b = BORDER                              o = POKE
    c = CONTINUE                            p = PRINT
    d = DIM                                 q = PLOT
    e = REM                                 r = RUN
    f = FOR                                 s = SAVE
    g = GO TO                               t = RANDOMIZE
    h = GO SUB                              u = IF
    i = INPUT                               v = CLS
    j = LOAD                                w = DRAW
    k = LIST                                x = CLEAR
    l = LET                                 y = RETURN
    m = PAUSE                               z = COPY

Also the ZX-Spectrum interpreter will insert a few spaces automatically, so the
previous listing will be expanded as follows:

   1 CLEAR : DIM t(91): INPUT "Players (1-2)?";f: RESTORE : READ n,t(41),t(42),t(50),t(51),t(1),z,p,z$
   2 LET p=3-p: LET q=z>1: DIM c(3): FOR a=1 TO 8: FOR b=1 TO 8: LET k=t(a*9+b+1): PRINT AT 18,3*b+2;b
   3 PRINT AT a+a,2;a; PAPER k+p*p*(a*9+b+1=z);AT a+a,3*b+1;"/  ";AT a+a+1,3*b+1;"___"
   4 LET c(k+1)=c(k+1)+1: NEXT b: NEXT a: PRINT ''" BLUE ";c(2);"x";c(3);" RED",: BORDER p
   5 LET e=c(1)*c(p+1)>0: INPUT ': IF e*f>=p THEN INPUT "Row (0-8)? ";a'"Col (0-8)? ";b
   6 FOR i=1 TO 62*e: LET z=CODE z$(i)-32+(a*9+b)*(a*b>0)*(b<9)
   7 BEEP .01,i: FOR j=0 TO 9*(t(z)=0)-1: LET d=j+INT (j/3)*6-10: LET w=z+d
   8 POKE n-2,8: IF t(w)=3-p THEN LET w=w+d: POKE (t(w)<>p)*n,1: LET w=w-d: LET t(w)=p: POKE (w<>z)*n,4
   9 NEXT j: GO TO 2+(8*(i*q<62)-5*(z>1=i))*(t(z)*j=0): DATA 23620,2,1,1,2,3,2,2
  10 NEXT i: BORDER 7: DATA "!2j+qX=0-ol_D?ZB]HT\@[QAKOF/.nmVMYPG>^ULC9876fedcka4,ph;1:bg5!"

To play this game, type letter r (command RUN will appear on screen), then press
ENTER.


-----
ABOUT
-----

This game was adapted from "1 Line Othello" developed by myself (Einar Saukas),
Digital Prawn, and Dr BEEP for the ZX-Spectrum in 2007, which was adapted from
"OTHELLO" originally developed by myself (Einar Saukas) and Eduardo Ito for the
ZX-Spectrum in 1989.

The complete list of variables in this version is as follows:

    t = array of current board position contents (0=empty, 1=player1, 2=player2)
    f = number of players (1 or 2)
    n = memory address that can be changed to "hack" a GOTO within the same line
    z = current move
    p = current player
    z$ = array with list of board positions ordered by strategical priority
    q = status of last move (0=pass, 1=valid)
    c = board positions counts, where:
        c(1) = total number of empty positions
        c(2) = total number of positions occupied by player1
        c(3) = total number of positions occupied by player2
    a = current row (1-8)
    b = current column (1-8)
    k = board content at row a, column b (0=empty, 1=player1, 2=player2)
    i = counter to traverse z$ (1 to 62)
    j = counter to traverse all possible alignment directions (0 to 8)
    d = alignment direction (-10, -9, -8, -1, 0, 1, 8, 9, 10)
    w = board position from current move towards a certain alignment direction

The purpose of each program line is described below:

    Line 1: Initialize game state
    Lines 2 to 4: Next player's turn, display board and score
    Line 5: If current player is human, ask for next move
    Line 6: Either traverse all board positions in priority order, or test a
            single position provided by human player
    Lines 7 and 8: Check if enemy disks would be captured in any direction, by 
            placing a new disk at the specified position
    Line 9: GOTO line 2 (if current player made valid move or valid pass), or
            GOTO line 5 (if human player tried invalid move or invalid pass), or
            GOTO line 10 (if game over, or there are more positions to check)
    Line 10: Reset border color if game over, also stores a list of board
            positions ordered by strategical priority


-------
CREDITS
-------

  "TENLINER OTHELLO" for the ZX-Spectrum
    by Einar Saukas (c) 2016.

  Based on "1 Line Othello" for the ZX-Spectrum
    by Einar Saukas, Digital Prawn, Dr BEEP (c) 2007.

  Based on "OTHELLO" for the ZX-Spectrum
    by Einar Saukas, Eduardo Ito (c) 1989.
